package com.yuzhenxin.coursesystem.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.framework.common.exception.ServiceException;
import com.yuzhenxin.coursesystem.config.enums.ErrorCodeConstants;
import com.yuzhenxin.coursesystem.controller.schedule.vo.ScheduleCreateReqDto;
import com.yuzhenxin.coursesystem.controller.schedule.vo.ScheduleQueryReqDto;
import com.yuzhenxin.coursesystem.entity.CourseDO;
import com.yuzhenxin.coursesystem.entity.ScheduleDO;
import com.yuzhenxin.coursesystem.entity.TeacherDO;
import com.yuzhenxin.coursesystem.mapper.ScheduleMapper;
import com.yuzhenxin.coursesystem.service.CourseService;
import com.yuzhenxin.coursesystem.service.ScheduleService;
import com.yuzhenxin.coursesystem.service.TeacherService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;

@Service
public class ScheduleServiceImpl extends ServiceImpl<ScheduleMapper, ScheduleDO> implements ScheduleService {

    @Autowired
    private ScheduleMapper scheduleMapper;

    @Autowired
    private TeacherService teacherService;

    @Autowired
    private CourseService courseService;

    @Override
    @Cacheable(value = "schedules", keyGenerator = "keyGenerator")
    public IPage<ScheduleDO> selectPage(ScheduleQueryReqDto reqDto) {
        Page<ScheduleDO> page = new Page<>(reqDto.getPageNo(), reqDto.getPageSize());
        String teacherName = reqDto.getTeacherName();
        String courseName = reqDto.getCourseName();
        LambdaQueryWrapper<ScheduleDO> queryWrapper = Wrappers.<ScheduleDO>lambdaQuery()
                .like(ObjectUtil.isNotEmpty(teacherName), ScheduleDO::getTeacherName, teacherName)
                .like(ObjectUtil.isNotEmpty(courseName), ScheduleDO::getCourseName, courseName);
        return scheduleMapper.selectPage(page, queryWrapper);
    }

    @Override
    public void add(ScheduleCreateReqDto reqDto) {
        TeacherDO teacherEntity = teacherService.getOne(Wrappers.<TeacherDO>lambdaQuery()
                .eq(TeacherDO::getNumber, reqDto.getTeacherNumber()));
        // Java8的optional替换if判断
        Optional.ofNullable(teacherEntity).orElseThrow(() -> ServiceException.of(ErrorCodeConstants.NO_SUCH_TEACHER));

        CourseDO courseEntity = courseService.getOne(Wrappers.<CourseDO>lambdaQuery()
                .eq(CourseDO::getNumber, reqDto.getCourseNumber()));
        Optional.ofNullable(courseEntity).orElseThrow(() -> ServiceException.of(ErrorCodeConstants.NO_SUCH_COURSE));

        // 设置并添加排课信息
        Long scheduleCount = scheduleMapper.selectCount(Wrappers.<ScheduleDO>lambdaQuery()
                .eq(ScheduleDO::getTeacherNumber, reqDto.getTeacherNumber())
                .eq(ScheduleDO::getCourseNumber, reqDto.getCourseNumber()));
        if (scheduleCount > 0) {
            throw ServiceException.of(ErrorCodeConstants.SCHEDULE_EXIST);
        }

        ScheduleDO scheduleDO = ScheduleDO.builder()
                .teacherNumber(teacherEntity.getNumber())
                .teacherName(teacherEntity.getName())
                .courseNumber(reqDto.getCourseNumber())
                .courseName(courseEntity.getName())
                .capacity(reqDto.getCapacity())
                .build();
        scheduleMapper.insert(scheduleDO);
    }

    @Override
    public void updateCapacityBySelectionIdList(List<Integer> selectionIdList) {
        scheduleMapper.updateCapacityBySelectionIdList(selectionIdList);
    }
}
